package com.lingxu.base.system.manage.util;

import com.lingxu.base.system.manage.model.*;

import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

public class TreeNodeTUtil<T extends TreeNodeT<T>> {
    public static final String ROOT_TYPE_ORG = "sysOrg_";
    public static final String ROOT_TYPE_DEPART = "sysDepart_";
    public static final String ROOT_TYPE_ROLE = "sysRole_";
    public static final String ROOT_TYPE_MENU = "sysMenu_";
    public static final String ROOT_TYPE_GROUP = "sysGroup_";



    public List<T> list2TreeNode(List<T> metaList){
        List<T> result=new ArrayList<>();
        Map<String ,T> treeTableId_TMap=new HashMap<>();
        for(T metaData:metaList){
            //tablePid和tableType相同时 代表是根
            if(!metaData.getTreeTablePid().equals(metaData.getTreeTableType())){
                //非根则将找此节点的父节点 放入其children中。
                T pDataInMap=treeTableId_TMap.get(metaData.getTreeTablePid());
                if(pDataInMap!=null){
                    pDataInMap.getChildren().add(metaData);
                }else{
                    for(T pData:metaList){
                        if(pData.getTreeTableId().equals(metaData.getTreeTablePid())){
                            pData.getChildren().add(metaData);
                            //将找到的结果加入map中 加速查找父节点
                            treeTableId_TMap.put(pData.getTreeTableId(),pData);
                            break;
                        }
                    }
                }

            }else{
                //是根则加入结果集中
                result.add(metaData);
            }
        }

        return result;
    }


//    public void namePlusUserCount(List<SysDepartTree> sysDepartTreeList) {
//        for(SysDepartTree sysDepartTree:sysDepartTreeList){
//            sysDepartTree.setName(sysDepartTree.getName()+"("+sysDepartTree.getManagerList().size()+"人)");
//        }
//    }

//    public void addUsers2Depart(List<TreeNode> treeNodeList, Map<String, List<SysUserTree>> departUsersMap) {
//        for(TreeNode nowNode:treeNodeList){
//            if(departUsersMap.get(nowNode.getTreeTableId())!=null){
//                List<SysUserTree> belongNowDepart=departUsersMap.get(nowNode.getTreeTableId());
//                nowNode.getChildren().addAll(belongNowDepart);
//            }
//        }
//    }
    public void countDepartUsers(List<TreeNode> treeNodeList){
        for(TreeNode nowNode:treeNodeList){

        }
    }

    /**
     *
     * @param treeNodeList 原始数据 即 处理的范围
     * @param nowTreeNode 当前待处理 节点
//     * @param path 由treeTableId组成的上一节点的路径
     * @param pTreeNode 父结点
     */
    public void setTreeUniqueId(List<TreeNode> treeNodeList,TreeNode nowTreeNode,TreeNode pTreeNode){

        if(nowTreeNode==null){
            //初始情况
            for(TreeNode treeNode:treeNodeList){
                //树中所有节点的唯一id目前全是自身id
                if(treeNode.getChildren()!=null && treeNode.getChildren().size()>0){
                    for(Object cTree:treeNode.getChildren()){
                        setTreeUniqueId(treeNodeList, (TreeNode) cTree,treeNode);
                    }
                }
            }
        }else{
            //非初始情况

            //值得注意的是递归的重覆盖情况，
            // （情况1）例如先赋值了根结点的子结点所有唯一id，但后续循环操作子结点时还用的是上次修改的根结点的值
            // 又由于路径是不断变长的.所以有解决方法1
            // 又由于对象的指针特性 所以使用父结点的指针（解决方法2）?而非父结点的某个值 或许可以解决

            //如果已存在的小于待赋值的 则是  情况1
//            String treeUniqueId=pTreeNode.getTreeUniqueId()+"_"+nowTreeNode.getTreeTableId();
//            if(nowTreeNode.getTreeUniqueId().length()<=treeUniqueId.length()){
//                nowTreeNode.setTreeUniqueId(treeUniqueId);
//            }
            nowTreeNode.setTreeUniqueId(pTreeNode.getTreeUniqueId()+"_"+nowTreeNode.getTreeTableId());

            if(nowTreeNode.getChildren()!=null && nowTreeNode.getChildren().size()>0){
                for(Object cTree:nowTreeNode.getChildren()){
                    setTreeUniqueId(treeNodeList, (TreeNode) cTree,nowTreeNode);
                }
            }
        }
    }

    //只要这个数 中的节点是唯一出现的 则只会在结果中出现一次
    public void tree2List(List<T> source,List<T> result){
        if (source!=null && !source.isEmpty()){
            for(T treeNode:source){
                result.add(treeNode);
                if(!treeNode.getChildren().isEmpty()){
                    tree2List(treeNode.getChildren(),result);
                }
            }
        }

    }




    //只能找目标节点的id 对应的路径节点
    public List<TreeNode> getPathByKey(List<TreeNode> sourceList,TreeNode targetNode){
        List<TreeNode> finalPathList = new ArrayList<>();
        try {
            for(TreeNode treeNode:sourceList){
                getNodePath(treeNode,finalPathList,targetNode);
            }
            return finalPathList;
        } catch (Exception e) {
            return finalPathList;
        }
    }

    //获取某节点的路径
    public void getNodePath(TreeNode nowNode,List<TreeNode> finalPathList,TreeNode targetNode) throws Exception {
        finalPathList.add(nowNode);
        if(nowNode.getTreeTableId().equals(targetNode.getTreeTableId())){
            throw new Exception("got you!");
        }
        if(nowNode.getChildren().size()>0){
            for(TreeNode treeNode:nowNode.getChildren()){
                getNodePath(treeNode,finalPathList,targetNode);
            }
            finalPathList.remove(finalPathList.size()-1);
        }else{
            finalPathList.remove(finalPathList.size()-1);
        }
    }

}
